// #include "../include/tcpService.h"
#include "tcpService.h"

TcpService::TcpService()
    // :toClientBuffer(1024), toRedisBuffer(1024)
{
    service_fd = socket(AF_INET, SOCK_STREAM, 0);
    if (service_fd == -1) {
        std::cerr << "socket error" << std::endl;
        return;
    }

    // 设置地址重用
    int opt = 1;
    if (setsockopt(service_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1) {
        std::cerr << "setsockopt error" << std::endl;
        return;
    }

    // 绑定地址和端口
    sockaddr_in address{};
    address.sin_family = AF_INET;
    address.sin_addr.s_addr = INADDR_ANY;
    address.sin_port = htons(PORT);
    if (bind(service_fd, (sockaddr *)&address, sizeof(address)) < 0) {
        perror("bind failed");
        close(service_fd);
        return;
    }

    // 创建epoll实例
    epoll_fd = epoll_create(1);
    if (epoll_fd == -1) {
        perror("epoll_create1 failed");
        close(service_fd);
        return;
    }

    toClientBuffer_fd = setRingBuffer();
    if (toClientBuffer_fd == -1) {
        close(service_fd);
        close(epoll_fd);
        return;
    }
    toClientBuffer = new RingBuffer(1024, toClientBuffer_fd);
    toRedisBuffer = new RingBuffer(1024, 0);

    // 添加服务器套接字到epoll
    epoll_event event{};
    event.events = EPOLLIN;
    event.data.fd = service_fd;
    if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, service_fd, &event) == -1) {
        perror("epoll_ctl failed");
        close(service_fd);
        close(epoll_fd);
        close(toRedisBuffer->getFd());
        close(toClientBuffer->getFd());
        return;
    }
}
TcpService::~TcpService()
{
    stop();
}
void TcpService::start()
{
    // 开始监听
    if (listen(service_fd, SOMAXCONN) < 0) {
        perror("listen failed");
        close(service_fd);
        return ;
    }
    std::cout << "Server is listening on port 12355..." << std::endl;

    // 用于设置最大事件量
    epoll_event events[MAX_EVENTS];
    while (true)
    { // 事件循环
        // epoll_wait会一直阻塞只有有事件发送
        int num_events = epoll_wait(epoll_fd, events, MAX_EVENTS, -1);
        if (num_events == -1) {
            perror("epoll_wait failed");
            break;
        }

        for (int i = 0; i < num_events; ++i) {
            // 处理新连接
            if (events[i].data.fd == service_fd)
            {
                sockaddr_in client_addr{};
                socklen_t client_len = sizeof(client_addr);
                int client_fd = accept(service_fd, (sockaddr *)&client_addr, &client_len);
                if (client_fd == -1)
                {
                    perror("accept failed");
                    continue;
                }
                // 设置为非阻塞模式
                set_nonblocking(client_fd);

                // 添加客户端到epoll
                epoll_event client_event{};
                client_event.events = EPOLLIN | EPOLLET; // 边缘触发模式
                client_event.data.fd = client_fd;
                if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, client_fd, &client_event) == -1) {
                    perror("epoll_ctl client add failed");
                    close(client_fd);
                    continue;
                }

                std::cout << "New connection from: "
                          << inet_ntoa(client_addr.sin_addr) << ":"
                          << ntohs(client_addr.sin_port) << std::endl;
            } else if (events[i].data.fd == toClientBuffer_fd){
                uint64_t value;
                read(toClientBuffer_fd, &value, sizeof(value));

                int client_fd;
                std::string data;
                toClientBuffer->pop(data, client_fd);

                write(client_fd, data.c_str(), data.size());
            } else {
                // 处理客户端数据
                int client_fd = events[i].data.fd;
                char buffer[BUFFER_SIZE];

                ssize_t bytes_read = read(client_fd, buffer, BUFFER_SIZE);
                if (bytes_read <= 0) {
                    // 连接关闭或错误
                    if (bytes_read == 0 || (bytes_read == -1 && errno != EAGAIN)) {
                        std::cout << "Connection closed" << std::endl;
                        epoll_ctl(epoll_fd, EPOLL_CTL_DEL, client_fd, nullptr);
                        close(client_fd);
                    }
                    continue;
                }

                // 简单回显处理
                buffer[bytes_read] = '\0';
                toRedisBuffer->push(buffer, client_fd);
            }
        }
    }
}
void TcpService::stop()
{
    close(service_fd);
    close(epoll_fd);
}

bool TcpService::readCommand(std::string &data, int& client_fd)
{
    return toRedisBuffer->pop(data, client_fd);
}

bool TcpService::response(std::string&& data, int client_fd)
{
    return toClientBuffer->push(std::move(data), client_fd);
}

int TcpService::set_nonblocking(int fd)
{
    int flags = fcntl(fd, F_GETFL, 0);
    if (flags == -1) return -1;
    return fcntl(fd, F_SETFL, flags | O_NONBLOCK);
}

int TcpService::setRingBuffer()
{
    int efd = eventfd(0, EFD_NONBLOCK); // 创建非阻塞的eventfd
    if (efd == -1) { 
        perror("eventfd failed");
        close(service_fd);
        close(epoll_fd);
        return -1;
    }
    // toRedisBuffer = new RingBuffer(1024, efd);
    epoll_event ev{};
    ev.events = EPOLLIN | EPOLLET;
    ev.data.fd = efd;
    if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, efd, &ev) == -1) {
        perror("epoll_ctl efd add failed");
        close(service_fd);
        close(epoll_fd);
        return -1;
    }
    return efd;
}
